From 29653cb5df15530e13c4a7eebb1ea078ab74dc39 Mon Sep 17 00:00:00 2001 From: robertl Date: Wed, 18 Sep 2002 14:41:41 +0000 Subject: [PATCH] 1. add csv_util.c and csv_util.h 2. change mxf.c to use csv_util / minor other changes 3. change csv to use csv_util 4. add OziExplorer 1.1 file format. 5. remove the extra MXF section from the README Thanks, Alex --- gpsbabel/csv_util.c | 205 +++++++++++++++++++++++++++++++++ gpsbabel/csv_util.h | 28 +++++ gpsbabel/ozi.c | 230 +++++++++++++++++++++++++++++++++++++ gpsbabel/reference/ozi.ozi | 13 +++ 4 files changed, 476 insertions(+) create mode 100644 gpsbabel/csv_util.c create mode 100644 gpsbabel/csv_util.h create mode 100644 gpsbabel/ozi.c create mode 100644 gpsbabel/reference/ozi.ozi diff --git a/gpsbabel/csv_util.c b/gpsbabel/csv_util.c new file mode 100644 index 000000000..4471b7bd1 --- /dev/null +++ b/gpsbabel/csv_util.c @@ -0,0 +1,205 @@ +/* + Utilities for parsing Comma Seperated Value files (CSV) + + Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include "defs.h" +#include "csv_util.h" + +#define MYNAME "CSV_UTIL" + +/*********************************************************************/ +/* csv_stringclean() - remove any unwanted characters from string. */ +/* returns MODIFIED string. */ +/* usage: csv_stringclean(stringtoclean, "&,\"") */ +/* (strip out ampersands, commas, and quotes. */ +/*********************************************************************/ +char * +csv_stringclean(char *string, const char *chararray) { + char * p; + char * lp; + const char * cp; + + if ((! string) || (! chararray)) { + return (string); + } + + /* lp - end of the original string */ + lp = string; + while (*lp) lp++; + + cp = chararray; + while (*cp) { + + + p = string; + while (*p) { + if (*cp == *p) { + /* we don't want this character! */ + strncpy(p, p+1, (lp - p)); + } + p++; + } + cp++; + } + + return (string); +} + + +/***********************************************************************************/ +/* csv_stringtrim() - trim whitespace and leading and trailing enclosures (quotes) */ +/* returns MODIFIED string. */ +/* usage: csv_stringtrim(string, "\"") */ +/***********************************************************************************/ +char * +csv_stringtrim(char *string, const char *enclosure) +{ + static char *p1 = NULL; + char *p2 = NULL; + size_t elen; + + if (!string) { + return (string); + } + + if (!enclosure) { + elen = 0; + } else { + elen = strlen(enclosure); + } + + p2 = string; + + /* advance pointer to the end of the string */ + while ((*p2) && (p2++)) { + } + p2--; + + /* trim off trailing whitespace */ + while (isspace(*p2)) { + *p2 = '\0'; + p2--; + } + + p1 = string; + + /* advance p1 past any leading whitespace */ + while (isspace(*p1)) { + p1++; + } + + /* if we have enclosures, yank them out in pairs */ + if (elen) { + while ((strncmp(p1, enclosure, elen) == 0) + && (strncmp(p2, enclosure, elen) == 0)) { + *p2 = '\0'; + p2--; + p1++; + } + } + + return (p1); +} + +/*****************************************************************************/ +/* csv_lineparse() - extract data fields from a delimited string. designed */ +/* to handle quoted and delimited data within quotes. */ +/* returns temporary COPY of delimited data field (use it */ +/* or lose it). */ +/* usage: p = csv_lineparse(string, ",", "\"", line) [initial call] */ +/* p = csv_lineparse(NULL, ",", "\"", line) [subsequent calls] */ +/*****************************************************************************/ +char * +csv_lineparse(char *stringstart, const char *delimited_by, + const char *enclosed_in, const int line_no) +{ + char *sp; + static char *p = NULL; + static char *tmp = NULL; + size_t dlen, elen; + int enclosedepth = 0; + short int dfound; + + if (!p) { + /* first pass thru */ + p = stringstart; + + if (!p) { + /* last pass out */ + return (NULL); + } + } + + if (tmp) { + free(tmp); + tmp = NULL; + } + + /* the beginning of the string we start with (this pass) */ + sp = p; + + /* length of delimiters and enclosures */ + dlen = strlen(delimited_by); + elen = strlen(enclosed_in); + + dfound = 0; + + while ((*p) && (!dfound)) { + if (strncmp(p, enclosed_in, elen) == 0) { + if (enclosedepth) + enclosedepth--; + else + enclosedepth++; + } + + if ((!enclosedepth) && (strncmp(p, delimited_by, dlen) == 0)) { + dfound = 1; + + } else { + p++; + } + } + + /* allocate enough space for this data field */ + tmp = (char *) calloc((p - sp) + 1, sizeof(char)); + + if (!tmp) { + fatal(MYNAME ": cannot allocate memory\n"); + } + + strncpy(tmp, sp, (p - sp)); + + if (dfound) { + /* skip over the delimited_by */ + p += dlen; + } else { + /* end of the line */ + p = NULL; + } + + if (enclosedepth != 0) { + fprintf(stderr, "%s: Warning- Unbalanced Field Enclosures (%s) on line %d\n", + MYNAME, enclosed_in, line_no); + } + + return (tmp); +} diff --git a/gpsbabel/csv_util.h b/gpsbabel/csv_util.h new file mode 100644 index 000000000..170cc43b5 --- /dev/null +++ b/gpsbabel/csv_util.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* function prototypes */ +char * +csv_stringtrim(char *string, const char *enclosure); + +char * +csv_lineparse(char *stringstart, const char *delimited_by, const char *enclosed_in, const int line_no); + +char * +csv_stringclean(char *string, const char *chararray); diff --git a/gpsbabel/ozi.c b/gpsbabel/ozi.c new file mode 100644 index 000000000..79841f6a0 --- /dev/null +++ b/gpsbabel/ozi.c @@ -0,0 +1,230 @@ +/* + OziExplorer Waypoint File Version 1.1 Format (.wpt) + Fixed-Length Comma Delimited + + Contributed to gpsbabel by Alex Mottram (geo_alexm at cox-internet.com) + + As described in Maptech Terrain Navigator Help File. + Tested against Terrain Navigator and ExpertGPS import/export .MXF files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "csv_util.h" +#include +#include /* for floor */ + +#define MYNAME "OZI" + +static FILE *file_in; +static FILE *file_out; + +static void +rd_init(const char *fname) +{ + file_in = fopen(fname, "r"); + if (file_in == NULL) { + fatal(MYNAME ": Cannot open %s for reading\n", fname); + } +} + +static void +rd_deinit(void) +{ + fclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = fopen(fname, "w"); + if (file_out == NULL) { + fatal(MYNAME ": Cannot open %s for writing\n", fname); + } +} + +static void +wr_deinit(void) +{ + fclose(file_out); +} + +static void +data_read(void) +{ + char buff[1024]; + char *s; + waypoint *wpt_tmp; + int i; + int linecount = 0; + + do { + linecount++; + memset(&buff, '\0', sizeof(buff)); + fgets(buff, sizeof(buff), file_in); + + if ((strlen(buff)) && (strstr(buff, ",") != NULL)) { + + wpt_tmp = calloc(sizeof(*wpt_tmp), 1); + + if (wpt_tmp == NULL) { + fatal(MYNAME ": cannot allocate memory\n"); + } + + /* data delimited by commas, possibly enclosed in quotes. */ + s = buff; + s = csv_lineparse(s, ",", "\"", linecount); + + i = 0; + while (s) { + switch (i) { + case 0: + /* sequence # */ + break; + case 1: + /* waypoint name */ + wpt_tmp->shortname = strdup(s); + + if (! wpt_tmp->shortname) + fatal(MYNAME, ": cannot allocate memory\n"); + + csv_stringtrim(wpt_tmp->shortname, ""); + break; + case 2: + /* degrees latitude */ + wpt_tmp->position.latitude.degrees = atof(s); + break; + case 3: + /* degrees longitude */ + wpt_tmp->position.longitude.degrees = atof(s); + break; + case 4: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + wpt_tmp->creation_time = (atof(s) - 25569.0) * 86400.0; + break; + case 5: + /* icons 0-xx */ + break; + case 6: + /* unknown - always 1 */ + break; + case 7: + /* display format options 0-8 */ + break; + case 8: + /* foreground color (0=black) */ + break; + case 9: + /* background color (65535=yellow)*/ + break; + case 10: + /* Description */ + wpt_tmp->description = strdup(s); + + if (! wpt_tmp->description) + fatal(MYNAME, ": cannot allocate memory\n"); + + wpt_tmp->description = csv_stringtrim(wpt_tmp->description, ""); + + break; + case 11: + /* pointer direction 0,1,2,3 bottom,top,left,right */ + break; + case 12: + /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */ + break; + case 13: + /* proximity distance - meters */ + break; + case 14: + /* altitude in feet */ + wpt_tmp->position.altitude.altitude_meters = (atof(s) * .3048); + break; + case 15: + /* waypoint text name size */ + break; + case 16: + /* bold checkbox (1=bold, default 0) */ + break; + case 17: + /* symbol size - 17 default */ + break; + default: + /* whoa! nelly */ + fprintf (stderr, "%s: Warning: data fields on line %d exceed specification.\n", + MYNAME, linecount); + break; + } + i++; + + s = csv_lineparse(NULL, ",", "\"", linecount); + } + + waypt_add(wpt_tmp); + + } else { + /* empty line */ + } + + } while (!feof(file_in)); +} + +static void +ozi_disp(waypoint * wpt) +{ + static int index = 0; + double alt_feet; + double ozi_time; + + ozi_time = (wpt->creation_time / 86400.0) + 25569.0; + alt_feet = (wpt->position.altitude.altitude_meters * 3.2808); + + csv_stringclean(wpt->description, ","); + csv_stringclean(wpt->shortname, ","); + + index++; + + fprintf(file_out, "%4d,%-14.14s,%11.6f,%11.6f,%011.5f,%3d,%2d,%2d,%10d,%10d,%-40.40s,%2d,%2d,%5d,%7.0f,%2d,%2d,%2d\n", + index, wpt->shortname, wpt->position.latitude.degrees, + wpt->position.longitude.degrees, ozi_time, 0, 1, 3, 0, 65535, + wpt->description, 0, 0, 0, alt_feet, 6, 0, 17); + +} + +static void +data_write(void) +{ + + fprintf(file_out, "OziExplorer Waypoint File Version 1.1\n"); + fprintf(file_out, "WGS 84\n"); + fprintf(file_out, "Reserved 2\n"); + fprintf(file_out, "Reserved 3\n"); + + waypt_disp_all(ozi_disp); +} + +ff_vecs_t ozi_vecs = { + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, +}; + diff --git a/gpsbabel/reference/ozi.ozi b/gpsbabel/reference/ozi.ozi new file mode 100644 index 000000000..bf7266ab2 --- /dev/null +++ b/gpsbabel/reference/ozi.ozi @@ -0,0 +1,13 @@ +OziExplorer Waypoint File Version 1.1 +WGS 84 +Reserved 2 +Reserved 3 + 1,GCEBB , 35.972033, -87.134700,25569.00000, 0, 1, 3, 0, 65535,Mountain Bike Heaven by susy1313 , 0, 0, 0, 0, 6, 0,17 + 2,GC1A37 , 36.090683, -86.679550,25569.00000, 0, 1, 3, 0, 65535,The Troll by a182pilot & Family , 0, 0, 0, 0, 6, 0,17 + 3,GC1C2B , 35.996267, -86.620117,25569.00000, 0, 1, 3, 0, 65535,Dive Bomber by JoGPS & family , 0, 0, 0, 0, 6, 0,17 + 4,GC25A9 , 36.038483, -86.648617,25569.00000, 0, 1, 3, 0, 65535,FOSTER by JoGPS & Family , 0, 0, 0, 0, 6, 0,17 + 5,GC2723 , 36.112183, -86.741767,25569.00000, 0, 1, 3, 0, 65535,Logan Lighthouse by JoGps & Family , 0, 0, 0, 0, 6, 0,17 + 6,GC2B71 , 36.064083, -86.790517,25569.00000, 0, 1, 3, 0, 65535,Ganier Cache by Susy1313 , 0, 0, 0, 0, 6, 0,17 + 7,GC309F , 36.087767, -86.809733,25569.00000, 0, 1, 3, 0, 65535,Shy's Hill by FireFighterEng33 , 0, 0, 0, 0, 6, 0,17 + 8,GC317A , 36.057500, -86.892000,25569.00000, 0, 1, 3, 0, 65535,GittyUp by JoGPS / Warner Parks , 0, 0, 0, 0, 6, 0,17 + 9,GC317D , 36.082800, -86.867283,25569.00000, 0, 1, 3, 0, 65535,Inlighting by JoGPS / Warner Parks , 0, 0, 0, 0, 6, 0,17 -- 2.30.2